Python数据分析模块pandas之数据处理

351次阅读
没有评论

共计 5536 个字符,预计需要花费 14 分钟才能阅读完成。

在了解完 pandas 的两种主要数据结构 Series 序列DataFrame 数据框,下面就来学习下 pandas 是怎么处理数据的。

处理数据一般分为几个阶段:数据整理与清洗、数据分析与建模、数据可视化,pandas 是处理数据的理想工具。

缺失值处理

None 是 Python 中自带的空对象。None 不能参与任何计算,object 类型的运算要比 int 类型的运算慢得多。

np.nan 是浮点类型,能参与到计算中,但计算的结果总是 NaN。可以使用 np.nan*()函数来计算 nan,此时会过滤掉 nan。

在 pandas 中,None 与 np.nan 都视作 np.nan。

找到缺失值

找有空的列:df.isnull().any(),any 只要有一个为 True 就为 True,类似 or。

找不为空的列:df.notnull().all(),all 必须全部为 True 才会是 True,类似 and。

找有空的行:df.isnull().any(axis=1)

找不为空的行:df.notnull().all(axis=1)

行过滤

cond = df.isnull().any(axis=1)
print(df[~cond])
# 或者
cond = df.notnull().all(axis=1)
print(df[cond])

列过滤

cond = df.isnull().any()
print(df.loc[:, ~cond])
# 或者
cond = df.notnull().all()
print(df.loc[:, cond])

dropna()

df.dropna()默认删除有空的行,删除有空的列使用 df.dropna(axis=1)。也可以选择过滤的方式,默认 how=”any”,how=”all” 必须所有数据都为 nan 才会删除。参数 inplace=True 会修改原数据。

填充空值

df.fillna(value=100)
df.fillna(method="ffill")  # 向前填充,向后填充是 bfill
df.fillna(method="ffill",axis=1)  # 向左填充,向右填充是 bfill

重复值处理

duplicated()函数用来检测重复行,返回元素为布尔类型的 Series 对象。

duplicated 默认保留重复第一行,keep=’last’ 保留重复最后一行,keep=False 不保留重复行。

df.duplicated(keep='first')
df.duplicated(subset=[" 列名 "])  # subset 参数为列名,对指定列进行去重操作

使用 drop_duplicates()函数删除重复行:df.drop_duplicates(subset=[" 列名 "], keep='last')

异常值处理

print(df.describe([0.01, 0.5, 0.99]))  # 自定义百分位数
print(df.describe([0.01, 0.5, 0.99]).T)  # 行列转置

Series 唯一值:print(df[0].unique())

按条件查询:

data = [["Alex", 100, 90], ["Bob", 91, 80], ["Clarke", 82, 88]]
df = pd.DataFrame(data, columns=["a", "b", "c"])
print(df.query("b==100"))  # 找到 b 列 =100 所有行
print(df.query("b in [90,100]"))
n = 100
print(df.query("b ==@n"))  # 使用变量

排序:

print(df.sort_values("b", ascending=False))  # 默认按列名升序排序,ascending=False 降序,axis=1 按行排序
print(df.sort_index(ascending=False))  # 默认按索引升序排序,axis=1 按列索引排序

行列操作

添加行

df = pd.DataFrame([["Alex", 100, 90], ["Bob", 91, 80], ["Clarke", 82, 88]])
df2 = pd.DataFrame([["Dick", 99, 77]])
df3 = pd.concat([df, df2], ignore_index=True)  # 默认上下合并
df4 = pd.concat([df, df2], keys=["a", "b"])  # keys 添加多层索引

删除行

data = [["Alex", 100, 90], ["Bob", 91, 80], ["Clarke", 82, 88]]
df = pd.DataFrame(data)
df.drop(1, inplace=True)  # 默认删除行
df.drop(1, axis=1, inplace=True)  # 删除列
df.drop(index=[1, 2])  # 删除多行
df.drop(columns=[1, 2])  # 删除多列

添加列

data = [["Alex", 100], ["Bob", 91], ["Clarke", 82]]
df = pd.DataFrame(data, columns=["Name", "Score_1"])
df.insert(1, column="Score_2", value=[90, 80, 88])

删除列

data = [["Alex", 100, 90], ["Bob", 91, 80], ["Clarke", 82, 88]]
df = pd.DataFrame(data, columns=["Name", "Score_1", "Score_2"])
del df["Score_1"]  # 使用 del 删除
df.pop("Name")  # 使用 pop()方法删除

数据合并

pd.concat()

外连接,类似并集,显示所有数据:

def make_df(indexs, columns):
    """ 生成 DataFrame"""
    data = [[str(j) + str(i) for j in columns] for i in indexs]
    df = pd.DataFrame(data, index=indexs, columns=columns)
    return df

df1 = make_df([1, 2, 3, 4], list("ABCD"))
df2 = make_df([5, 2, 3, 10], list("BCDE"))
df3 = pd.concat([df1, df2])

内连接,类似交集,只连接匹配的项:df3 = pd.concat([df1, df2], join="inner")

merge()

也可以使用 merge()合并数据,类似 MySQL 中表和表合并。merge 与 concat 的区别在于,merge 需要依据某一共同的行或列来进行合并。使用 merge 合并时,会自动根据两者相同 column 名称的那一列,作为 key 来进行合并,每一列元素的顺序不要求一致。

有多列名称相同,可指定一列作为连接字段:

df1 = make_df([1, 2, 3], list("ABC"))
df2 = make_df([2, 3, 4], list("BCD"))
print(df1.merge(df2, on="C"))

可以配合 suffixes 参数指定冲突列名:

df1 = make_df([1, 2, 3], list("ABC"))
df2 = make_df([2, 3, 4], list("BCD"))
print(df1.merge(df2, on="C", suffixes=["_df1", "_df2"]))

如果没有相同列名,需使用来指定 2 个表中的不同列作为连接字段:

df1 = make_df([1, 2, 3], list("ABC"))
df2 = make_df([2, 3, 4], list("BD"))
print(df1.merge(df2, left_on="B", right_on="B"))

也可以使用行索引作为连接字段:

df1 = make_df([1, 2, 3], list("ABC"))
df2 = make_df([2, 3, 4], list("DE"))
print(df1.merge(df2, left_index=True, right_index=True))

merge 默认是内连接,可以使用 how 参数指定连接方式:

df1 = make_df([1, 2, 3], list("ABC"))
df2 = make_df([2, 3, 4], list("CD"))
print(df1.merge(df2, how="outer"))

左连接:how=”left”,右连接:how=”right”。

数据映射

元素替换

使用 replace 函数,对 values 进行替换操作。

import pandas as pd
import numpy as np

data = [{"Name": "Alex", "Age": 12}, {"Name": "Bob", "Age": 16, "Sex": "1"}]
df = pd.DataFrame(data)
df.replace({np.nan: 0}, inplace=True)

map()函数

map 一般用在 Series 数据结构,不能用于 DataFrame,适合处理某一单独列,在 map()函数中可以使用 lambda。

def fn(sex):
    if sex == "1":
        return " 男 "
    elif sex == "2":
        return " 女 "
    else:
        return ""

data = [{"Name": "Alex", "Age": 12}, {"Name": "Bob", "Age": 16, "Sex": "1"}]
df = pd.DataFrame(data)
df[" 性别 "] = df["Sex"].map(fn)

apply()函数

既支持 Series,也支持 DataFrame。

df["Age"] = df["Age"].apply(lambda x: " 成年 " if x >= 18 else " 未成年 ")

print(df.apply(lambda x: x.max()))  # 对每列操作

print(df.applymap(lambda x: x + 100))  # 对所有 DataFrame 元素操作

transform()函数

既支持 Series,也支持 DataFrame。

print(df[1].transform([np.sqrt, np.exp]))  # 可以执行多项计算
print(df.transform(lambda x: x + 10))  # 处理每一列
print(df.transform(lambda x: x + 10, axis=1))  # 处理每一行

修改索引

替换索引:

data = [{"Name": "Alex", "Age": 12}, {"Name": "Bob", "Age": 16, "Sex": "1"}]
df = pd.DataFrame(data)
df.rename(index={0: 10}, inplace=True)  # 修改行索引名
df.rename(columns={"Name": " 姓名 "}, inplace=True)  # 修改列索引名

重置索引:df.reset_index(inplace=True)

设置索引:df.set_index(keys=["Age"], inplace=True)

数据筛选

data = [["Alex", 100, 90], ["Bob", 91, 80], ["Clarke", 82, 88]]
df = pd.DataFrame(data, index=["one", "two", "three"], columns=["A", "B", "C"])

f1 = df.filter(items=["A", "C"])  # 按名称选择列
f2 = df.filter(regex="e$", axis=0)  # 按正则表达式选择列索引名以 e 结尾,axis= 0 表示对行操作
f3 = df.filter(like="t", axis=0)  # 列索引名中含有 t 的
f4 = df.filter(like="t", axis=0).filter(items="B")  # 连续筛选

抽样

使用 take()函数排序,借助 np.random.permutation()函数随机排序。

无放回抽样:

data = [["Alex", 100, 90], ["Bob", 91, 80], ["Clarke", 82, 88]]
df = pd.DataFrame(data, index=["one", "two", "three"], columns=["A", "B", "C"])
print(df.take(np.random.permutation([0, 1, 2])))

有放回抽样:print(df.take(np.random.randint(0, 3, size=6)))

分组聚合

df = pd.DataFrame(
    {"color": ["red", "red", "blue", "yellow", "blue"],
        "price": [1, 3, 5, 6, 7],
    }
)
df2 = df.groupby("color").sum()  # 先按 color 进行分组,再聚合
print(df2)

分箱操作

分箱操作就是将连续型数据离散化,分为等距分箱和等频分箱。

等距分箱:

data = np.random.randint(0, 100, size=(5, 3))
df = pd.DataFrame(data, columns=["A", "B", "C"])
print(pd.cut(df.A, bins=4))
# bins 指定分箱断点。默认是左开右闭,right=False 左闭右开。参数 labels 指定分箱后分类的标签
print(pd.cut(df.A, bins=[0, 60, 80, 90, 100], right=False, labels=["D", "C", "B", "A"]))

等频分箱:pd.qcut(df.A, q=4, labels=["D", "C", "B", "A"])

正文完
 0
阿伯手记
版权声明:本站原创文章,由 阿伯手记 于2024-01-18发表,共计5536字。
转载说明:本站原创内容,除特殊说明外,均基于 CC BY-NC-SA 4.0 协议发布,转载须注明出处与链接。
评论(没有评论)
验证码

阿伯手记

阿伯手记
阿伯手记
喜欢编程,头发渐稀;成长路上,宝藏满地
文章数
767
评论数
207
阅读量
682073
今日一言
-「
热门文章
职场救急!AI请假话术生成器:1秒定制高通过率理由

职场救急!AI请假话术生成器:1秒定制高通过率理由

超级借口 不好开口?借口交给我!智能生成工作请假、上学请假、饭局爽约、约会拒绝、邀约推辞、万能借口等各种借口理...
夸克网盘快传助手提高非VIP下载速度

夸克网盘快传助手提高非VIP下载速度

夸克网盘限速这个大家都知道,不开会员差不多限速在几百 K。那有没有办法在合法合规途径加速下载夸克网盘呢?这里推...
TVAPP:开源电视盒子资源库,一键打造家庭影院

TVAPP:开源电视盒子资源库,一键打造家庭影院

导语 TVAPP 是一个专为 Android TV 电视盒子用户打造的开源影音资源库,集成了影视、直播、游戏等...
巴别英语:用美剧和TED演讲轻松提升英语听力与口语

巴别英语:用美剧和TED演讲轻松提升英语听力与口语

还在为枯燥的英语学习而烦恼吗?巴别英语通过创新的美剧学习模式,让英语学习变得生动有趣。平台提供海量美剧和 TE...
Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 是一款在线中文姓名生成器,可在几秒内生成符合个人需求的中文名字。...
2025年12月 每日精选

2025年12月 每日精选

关于每日精选栏目 发现一些不错的资源,点击 这里 快速投稿。 12 月 26 日 .ax 顶级域 目前全球唯一...
123云盘限时福利:登录即送1个月VIP尊享权益!

123云盘限时福利:登录即送1个月VIP尊享权益!

🎁  零成本体验 20T 超大空间与会员加速通道 🎉 活动亮点 登录即送:无需任何复杂操作,登录账号直接领取 ...
最新评论
阿伯手记 阿伯手记 发了:https://aboss.top/moments/1064
吴蛋蛋 吴蛋蛋 快发小年快乐
吴蛋蛋 吴蛋蛋 Ask4Me,这个之前看server酱接入了
15220202929 15220202929 怎么用
八对 八对 麻烦大佬更新下【堆新】的友链站名:八对星星描述:极目星视穹苍无界•足履行者大地有疆链接:https://8dui.com图标:https://cf.8dui.com/logo.webp横标:https://cf.8dui.com/logo-w.webp订阅:https://8dui.com/rss.xml
三毛笔记 三毛笔记 已添加
DUINEW DUINEW 已添加贵站,期待贵站友链~博客名称:堆新博客地址:https://duinew.com/博客描述:堆新堆新,引力向新!——堆新(DUINEW)博客头像:https://d.duinew.com/logo.webp横版头像:https://d.duinew.com/logo-w.webp博客订阅:https://duinew.com/rss.xml
hedp hedp 没看懂
bingo bingo 直接生成就可以啦,也可以添加一些选项
热评文章
夸克网盘快传助手提高非VIP下载速度

夸克网盘快传助手提高非VIP下载速度

夸克网盘限速这个大家都知道,不开会员差不多限速在几百 K。那有没有办法在合法合规途径加速下载夸克网盘呢?这里推...
Short-Link 免费开源短网址程序,基于Fastify、Vercel和Supabase构建

Short-Link 免费开源短网址程序,基于Fastify、Vercel和Supabase构建

Short-Link 是一款基于 Fastify、Vercel 和 Supabase 构建的 URL 缩短服务...
清华大学官方免费DeepSeek教程

清华大学官方免费DeepSeek教程

AI 领域近期最引人注目的焦点当属 DeepSeek,这款由中国创新企业深度求索研发的人工智能工具,正以开放源...
Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 在线中文姓名生成器

Chinese Name Generator 是一款在线中文姓名生成器,可在几秒内生成符合个人需求的中文名字。...
2026年2月 每日精选

2026年2月 每日精选

关于每日精选栏目 发现一些不错的资源,点击 这里 快速投稿。 2 月 17 日 国家全民健身信息服务平台 过年...
DrawLink:一键生成链接视觉卡片,提升分享点击率

DrawLink:一键生成链接视觉卡片,提升分享点击率

小贴士 :此站或已变迁,但探索不止步。我们已为您备好「类似网站」精选合集,相信其中的发现同样能为您带来惊喜。
WebRTC Screen Mirror:基于浏览器免费开源投屏神器,可实现低延迟、跨平台屏幕共享

WebRTC Screen Mirror:基于浏览器免费开源投屏神器,可实现低延迟、跨平台屏幕共享

WebRTC Screen Mirror 是一款基于 WebRTC 技术的在线屏幕共享工具,它利用浏览器内置的...